﻿using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Text;

namespace RabbitMQServer
{
    class Program
    {
        //API代码：https://www.cnblogs.com/personblog/p/10681741.html
        //命令：https://www.jianshu.com/p/f677fde4f0fb
        //集群(主备模式、远程模式、镜像模式、多活模式)：https://www.jianshu.com/p/b7cc32b94d2a
        //复杂的应用场景
        //刷面试题
        static void Main(string[] args)
        {
            Console.WriteLine("Welcome to RabbitMQ Product!");
            DirectExchangeSendMsg();//简单模式
            //TopicExchangeSendMsg();//topic模式
            Console.WriteLine("按任意值，退出程序");
            Console.ReadKey();
        }
        /// <summary>
        /// 连接配置  Connection连接
        /// </summary>
        private static readonly ConnectionFactory rabbitMqFactory = new ConnectionFactory()
        {
            UserName = "guest",
            Password = "guest",
            Port = 5672,//端口号
            VirtualHost = "/", //主机名  默认为"/"
            //AutomaticRecoveryEnabled=true//默认为true
        };
        /// <summary>
        /// 路由名称
        /// </summary>
        const string ExchangeName = "howdy.exchange";

        //队列名称
        const string QueueName = "howdy.queue";

        /// <summary>
        /// 路由名称
        /// </summary>
        const string TopExchangeName = "topic.howdy.exchange";

        //队列名称
        const string TopQueueName = "topic.howdy.queue";


        /// <summary>
        ///  单点精确路由模式：简单模式
        /// </summary>
        public static void DirectExchangeSendMsg()
        {
            //创建连接Connection
            using (IConnection conn = rabbitMqFactory.CreateConnection())
            {
                //创建通道/创建信道   
                using (IModel channel = conn.CreateModel())
                {
                    //声明交换器
                    channel.ExchangeDeclare(ExchangeName, ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);
                    //声明队列
                    channel.QueueDeclare(QueueName, durable: true, autoDelete: false, exclusive: false, arguments: null);
                    //交换器与队列进行绑定
                    channel.QueueBind(QueueName, ExchangeName, routingKey: QueueName);

                    //发送一条带有headers的消息
                    Dictionary<string, object> headers = new Dictionary<string, object>();
                    headers.Add("location","here");
                    headers.Add("time", "today");
                    var props = channel.CreateBasicProperties();
                    props.Headers = headers;//发送一条带有header的消息
                    props.Expiration = "60000";//发送一条带有过期时间的消息

                    props.UserId = "1";

                    //var props = channel.CreateBasicProperties();
                    props.Persistent = true;
                    //备注：需要向控制台输入文字后，才会进行发送消息
                    //.net core控制台需要以数字或字母结尾时，按回车键才会有反应，才可以继续执行
                    string vadata = Console.ReadLine();
                    while (vadata != "exit")
                    {
                        var msgBody = Encoding.UTF8.GetBytes(vadata);
                        //通过交换器BasicPublish数据到队列
                        channel.BasicPublish(exchange: ExchangeName, routingKey: QueueName, basicProperties: props, body: msgBody);
                        Console.WriteLine(string.Format("***发送时间:{0}，发送完成，输入exit退出消息发送",
                            DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                        vadata = Console.ReadLine();
                    }
                }
            }
        }
        /// <summary>
        /// 发布订阅模式
        /// </summary>
        public static void ReleaseSubscriptionSendMsg()
        {
           
        }
        /// <summary>、
        /// topic 模糊匹配模式：符号“#”匹配一个或多个词，符号“*”匹配不多不少一个词。因此“log.#”能够匹配到“log.info.oa”，但是“log.*” 只会匹配到“log.error”
        /// </summary>
        public static void TopicExchangeSendMsg()
        {
            using (IConnection conn = rabbitMqFactory.CreateConnection())
            {
                using (IModel channel = conn.CreateModel())
                {
                    channel.ExchangeDeclare(TopExchangeName, ExchangeType.Topic, durable: false, autoDelete: false, arguments: null);
                    channel.QueueDeclare(TopQueueName, durable: false, autoDelete: false, exclusive: false, arguments: null);
                    channel.QueueBind(TopQueueName, TopExchangeName, routingKey: TopQueueName);
                    //var props = channel.CreateBasicProperties();
                    //props.Persistent = true;
                    string vadata = Console.ReadLine();
                    while (vadata != "exit")
                    {
                        var msgBody = Encoding.UTF8.GetBytes(vadata);
                        channel.BasicPublish(exchange: TopExchangeName, routingKey: TopQueueName, basicProperties: null, body: msgBody);
                        Console.WriteLine(string.Format("***发送时间:{0}，发送完成，输入exit退出消息发送", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                        vadata = Console.ReadLine();
                    }
                }
            }
        }
    }
}
